# -*- coding: utf-8 -*-

# -------------------------------
# Author    : linlingwei
# Email     : 951035650@qq.com
# File Name : leg.py
# Date      : 2018/11/12
# IDE       : PyCharm
# Version   : 1.0.2
# -------------------------------
__author__ = "lin lingwei"

import maya.cmds as mc

import configs.constants.attribute_constant as ac
import configs.constants.nodeType_constant as nc
import configs.constants.suffix_constant as sc
import configs.constants.body_constant as bc
import configs.constants.global_constant as gc

import scripts.commonCmds as con
import scripts.curveCmds as crc

import rig.body.bCore as bCore
import rig.body.arm as arm
import rig.jointTool as jt
import rig.sample as sample


import rig.rpIkhandle as rik


class Leg(arm.Arm):
    
    def __init__(self,localMake,localPrefix=""):
        super(Leg,self).__init__(localTag=bc.gLeg,
                                 localMake=localMake,
                                 localPrefix=localPrefix)
        
        self.seq = [bc.gThigh,bc.gLeg, bc.gShank, bc.gAnkle,bc.gToeA, bc.gToe, bc.gToeTip]
        self.localSeq = [bc.gThigh,bc.gLeg, bc.gShank, bc.gAnkle,bc.gToeA, bc.gToe, bc.gToeTip]

    def create(self, mirror=False):
        self.localPrefix = gc.gLeft
        if mirror:
            self.localPrefix = gc.gRight
            self.local_colorId = bc.cRight
        self.refresh_localName()
        self.localInit()

        self.shouler_setting(mirror,bc.gThigh)

        drjot_list = self.create_joint(bc.gDr, self.seq[1:], mirror=mirror)
        
        ikjot_list = self.fik_setting(mirror,)
        fkjot_list = self.fk_setting(mirror,index=[1,-1])
        
        self.ikfkSwitch(ikjot_list,fkjot_list,drjot_list)
        mc.connectAttr(con.lAttr(self.localBridge,bc.aIkSwitch),
                       con.lAttr(con.lname(self.localName,bc.gIk,sc.sGrp),"v"))
        fh_tag = fkjot_list[0].replace(sc.sJot, sc.sCtr)
        mc.connectAttr(con.lAttr(self.localBridge,bc.aFkSwitch),fh_tag+"_Zero.v")

        mc.parent(drjot_list[0],self.localPrefixGrp)
        
        foot_trans = self.foot_control(mirror)
        for dj , ft in zip(drjot_list[2:],foot_trans):
            mc.parentConstraint(dj,ft,mo=True)
            
        mc.hide(fkjot_list[2].replace(sc.sJot,sc.sCtr)+"_Zero")
        
        self.ikfk_ctr(drjot_list[2])
        return

    def fik_setting(self, mirror=False,):
        root=bc.gLeg
        handle = bc.gAnkle
        lname_ik = con.lname(self.localName, bc.gIk)
        tmpData = self.parsePartTemplate()
        # armPolar = crc.objToControl(tmpData[bc.gForeArmPolar], con.lname(self.localName,bc.gPolar))
    
        # ik setting
        ikjot_list = self.create_joint(bc.gIk, self.seq[1:], mirror=mirror)
        mc.hide(ikjot_list[0])
    
        aikobj = rik.RpIkhandle(con.lname(lname_ik))
        aikobj.create(ikjot_list[0], ikjot_list[2])
        aikobj.jot_root()
        aikobj.stretch()
        aikobj.auto_polar()
        aikobj.lockPolar()
        auto_flw = aikobj.polar_follow()
        
        toea_obj = rik.RpIkhandle(con.lname(lname_ik,bc.gToeA))
        toea_obj.create(ikjot_list[2], ikjot_list[3])

        toe_obj = rik.RpIkhandle(con.lname(lname_ik,bc.gToe))
        toe_obj.create(ikjot_list[3], ikjot_list[4])

        toetip_obj = rik.RpIkhandle(con.lname(lname_ik,bc.gToeTip))
        toetip_obj.create(ikjot_list[4], ikjot_list[5])
        
        # --- control
        arm_ctr = crc.objToControl(tmpData[handle], name=con.lname(lname_ik),
                                   colorId=self.local_colorId,
                                   ctrlShape="cube",)
        # arm_loc = con.objToLocator(arm_ctr,name=con.lname(self.localName,"output"))
        mc.setAttr(arm_ctr+".r",0,0,0)
        if mirror:con.localMirror(arm_ctr,"world")
        mc.parent(arm_ctr, aikobj.localGrp)
        mc.parent(aikobj.ikhandle_loc, arm_ctr)
        arm_grp = con.emptyGroup(arm_ctr)
        # mc.orientConstraint(arm_ctr, ikjot_list[-1], mo=True)
        con.lockHideAttr(arm_ctr,["sx","sy","sz","v"])

        polar_ctr = crc.objToControl(tmpData[bc.gPolar], name=con.lname(lname_ik, bc.gPolar),
                                     colorId=self.local_colorId,
                                     ctrlShape="sphere", mirror=mirror)
        mc.parent(polar_ctr, aikobj.localGrp)
        mc.parent(aikobj.polarObj, polar_ctr)
        polar_grp = con.emptyGroup(polar_ctr)
        mc.setAttr(aikobj.polarObj + ".tz", 0)
        con.lockHideAttr(polar_ctr,ignore=["tx","ty","tz"])

        armRoot_ctr = crc.objToControl(tmpData[root], name=con.lname(lname_ik, bc.gRoot),
                                       colorId=self.local_colorId,
                                       ctrlShape="sphere", mirror=mirror)
        mc.delete(mc.aimConstraint(arm_ctr, armRoot_ctr, mo=False,
                                   aimVector=[1, 0, 0], upVector=[0, 0, -1], worldUpType="object",
                                   worldUpObject=polar_ctr))
        mc.parent(armRoot_ctr, aikobj.localGrp)
        mc.parent(aikobj.jotRoot, armRoot_ctr)
        armRoot_grp = con.emptyGroup(armRoot_ctr)
        con.lockHideAttr(armRoot_ctr,ignore=["tx","ty","tz"])

        mc.parent(aikobj.localGrp, self.localPrefixGrp)
    
        hobj = self.followHook(arm_grp[1], fowAttr=(ac.local, bc.gShoulder))
        mc.parent(hobj[ac.local], self.transfer)
        mc.parent(hobj[bc.gRoot], arm_grp[0])
        mc.connectAttr(hobj[sc.sBridge] + ".t", arm_grp[1] + ".t")
        mc.connectAttr(hobj[sc.sBridge] + ".r", arm_grp[1] + ".r")
    
        mc.parent(hobj[bc.gShoulder], self.root_flw)
        mc.parentConstraint(self.root_flw, armRoot_grp[1], mo=True)
    
        mc.addAttr(polar_ctr, ln="auto_align", at="long", dv=1, min=0, max=1, k=True)
        polar_pat = mc.pointConstraint(auto_flw, polar_grp[1], mo=True)[0]
        mc.connectAttr(con.lAttr(polar_ctr, "auto_align"), polar_pat + '.%sW%s' % (auto_flw, 0))
    
        con.transferAttr(hobj[sc.sBridge], arm_ctr, (bc.aFollow,))
        con.hideJoint(aikobj.jotlist)
        
        fas = self.foot_attr_setting(mirror)
        mc.parent(fas[bc.gAnkle],arm_ctr)
        mc.parent(toea_obj.localGrp,toe_obj.localGrp,aikobj.ikhandle_loc,fas[bc.gToe])
        mc.parent(toetip_obj.localGrp,fas[bc.gToeTip])

        attrlist = (bc.aRoll,bc.aRollRange,bc.aStandrx,
                                bc.aTiprx ,bc.aRevHeelRoll,bc.aRevBallRoll,
                                bc.aTipry,bc.aStandry,bc.aHeelry,bc.aHeelrx,
                                bc.aSide,)
        con.transferAttr(self.localBridge,arm_ctr,attrlist)
        con.transferAttr(aikobj.localBridge,arm_ctr,(ac.stretch_switch,))
        con.transferAttr(aikobj.localBridge,polar_ctr,(ac.lock_polar,))
        return ikjot_list

    def foot_attr_setting(self, mirror=False):
        tmpDict = self.parsePartTemplate()

        seq = [bc.gFootOutside, bc.gFootInside, bc.gHeel, bc.gToeTip, bc.gToe]
        setDict = dict()
        ankle = con.objToType(tmpDict[bc.gAnkle], name=con.lname(self.localName, "Foot"))
        setDict[bc.gAnkle] = ankle
        if mirror: con.localMirror(ankle,"world")
    
        pat = ankle
        for s in seq:
            trans = con.objToType(tmpDict[s], name=con.lname(self.localName, s, "pivot"),)
            mc.parent(trans, pat)
            pat = trans
            setDict[s] = trans
    
        if mirror:
            tmpMirror = mc.createNode(nc.tTransform, name="tmpMirror")
            mc.parent(setDict[seq[0]], tmpMirror)
            mc.setAttr(tmpMirror + ".sx", -1)
            mc.parent(setDict[seq[0]], ankle)
            mc.delete(tmpMirror)
    
        con.emptyGroup(setDict[seq[0]],["Zero"])
    
        attr = bc.aTiprx
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, min=0, k=True)
        aTiprxPma = mc.createNode(nc.tPlusMinusAverage, name=con.lname(setDict[bc.gToeTip],bc.aTiprx, sc.sPma))
        mc.connectAttr("{}.{}".format(self.localBridge, attr), aTiprxPma + ".input1D[0]")
        mc.connectAttr(aTiprxPma + ".output1D", setDict[bc.gToeTip] + ".rx")
    
        attr = bc.aTipry
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, k=True)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), setDict[bc.gToeTip] + ".ry")
    
        attr = bc.aHeelrx
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, max=0, k=True)
        aHeelrxPma = mc.createNode(nc.tPlusMinusAverage, name=con.lname(setDict[bc.gHeel], bc.aHeelrx, sc.sPma))
        mc.connectAttr("{}.{}".format(self.localBridge, attr), aHeelrxPma + ".input1D[0]")
        mc.connectAttr(aHeelrxPma + ".output1D", setDict[bc.gHeel] + ".rx")
    
        attr = bc.aHeelry
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, k=True)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), setDict[bc.gHeel] + ".ry")
    
        attr = bc.aInside
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, min=0, k=True)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), setDict[bc.gFootInside] + ".rz")
    
        attr = bc.aOutside
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, min=0, k=True)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), setDict[bc.gFootOutside] + ".rz")
    
        con.insertNeg(setDict[bc.gFootOutside], "rz")
        con.insertNeg(setDict[bc.gFootInside], "rz")
    
        attr = bc.aSide
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, k=True)
    
        attr = bc.aStandry
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, k=True)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), setDict[bc.gToe] + ".ry")
    
        attr = bc.aStandrx
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, min=0, k=True)
        aStandrxPma = mc.createNode(nc.tPlusMinusAverage, name=con.lname(setDict[bc.gToe], bc.aHeelrx, sc.sPma))
        mc.connectAttr("{}.{}".format(self.localBridge, attr), aStandrxPma + ".input1D[0]")
        mc.connectAttr(aStandrxPma + ".output1D", setDict[bc.gToe] + ".rx")
    
        attr = bc.aRevBallRoll
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, k=True)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), setDict[bc.gToe] + ".rz")
    
        attr = bc.aRevHeelRoll
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, k=True)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), setDict[bc.gHeel] + ".rz")
    
        # inSideCon
    
        bre = self.localBridge
    
        inSideCon = mc.createNode('condition', name=con.lname(self.localName, bc.aOutside, sc.sCon))
    
        mc.connectAttr(bre + '.%s' % bc.aSide, inSideCon + '.firstTerm')
        mc.setAttr(inSideCon + '.secondTerm', 0)
        mc.setAttr(inSideCon + '.operation', 2)
        mc.connectAttr(bre + '.%s' % bc.aSide, inSideCon + '.colorIfTrueR')
        mc.setAttr(inSideCon + '.colorIfFalseR', 0)
    
        mc.connectAttr(inSideCon + '.outColorR', bre + ".%s" % bc.aOutside)
    
        # outSideCon
        outSideCon = mc.createNode('condition', name=con.lname(self.localName, bc.aInside, sc.sCon))
        mc.connectAttr(bre + '.%s' % bc.aSide, outSideCon + '.firstTerm')
        mc.setAttr(outSideCon + '.secondTerm', 0)
        mc.setAttr(outSideCon + '.operation', 4)
        mc.connectAttr(bre + '.%s' %bc. aSide, outSideCon + '.colorIfTrueR')
        mc.setAttr(outSideCon + '.colorIfFalseR', 0)
    
        mc.connectAttr(outSideCon + '.outColorR', bre + ".%s" % bc.aInside)
    
        # add roll attribute
        attr = bc.aRoll
        mc.addAttr(self.localBridge, ln=attr, at="float", dv=0, k=True)
        mc.addAttr(self.localBridge, ln=bc.aRollRange, at="float", dv=40, k=True)
    
        rSr = mc.createNode("setRange", name=con.lname(self.localName, attr, sc.sSr))
        mc.connectAttr(self.localBridge + "." + bc.aRollRange, rSr + ".mx")
        mc.connectAttr(self.localBridge + "." + bc.aRollRange, rSr + ".omx")
        mc.setAttr(rSr + ".nx", 0)
        mc.setAttr(rSr + ".onx", 0)
    
        mc.connectAttr("{}.{}".format(self.localBridge, attr), rSr + ".vx")
        mc.connectAttr(rSr + ".ox", aStandrxPma + ".input1D[1]")
    
        rpma = mc.createNode(nc.tPlusMinusAverage, name=con.lname(self.localName, attr, sc.sPma))
        mc.connectAttr("{}.{}".format(self.localBridge, attr), rpma + ".input1D[0]")
        mc.connectAttr(self.localBridge + "." + bc.aRollRange, rpma + ".input1D[1]")
        mc.setAttr(rpma + ".op", 2)
    
        rcon = mc.createNode("condition", name=con.lname(self.localName, attr, sc.sCon))
        mc.connectAttr(rpma + ".output1D", rcon + ".ft")
        mc.setAttr(rcon + ".st", 0)
        mc.setAttr(rcon + ".op", 2)
        mc.connectAttr(rpma + ".output1D", rcon + ".ctr")
        mc.setAttr(rcon + ".cfr", 0)
    
        mc.connectAttr(rcon + ".ocr", aTiprxPma + ".input1D[1]")
    
        heelCon = mc.createNode("condition", name=con.lname(self.localName, attr + bc.aHeelrx, sc.sCon))
        mc.connectAttr("{}.{}".format(self.localBridge, attr), heelCon + ".ft")
        mc.setAttr(heelCon + ".st", 0)
        mc.setAttr(heelCon + ".op", 4)
        mc.connectAttr("{}.{}".format(self.localBridge, attr), heelCon + ".ctr")
        mc.setAttr(heelCon + ".cfr", 0)
        mc.connectAttr(heelCon + ".ocr", aHeelrxPma + ".input1D[1]")
        
        
        
        return setDict
    
    def foot_control(self,mirror=False):
        
        fkjot_list = self.create_joint("trans", self.seq[3:], )
        jot_list = sample.selectJointChain(fkjot_list,con.lname(self.localName,"foot"),
                                           mirror=mirror,colorId=self.local_colorId)
        mc.delete(fkjot_list)
        mc.parent( jot_list[0].replace(sc.sJot, sc.sCtr)+"_Zero",self.localGrp)
        pat = None
        trans_list = []
        for jot in jot_list:
            jot_ctr = jot.replace(sc.sJot, sc.sCtr)
            trans = con.objToType(jot_ctr,name=con.lname(jot,"trans"),mode=1)
            if pat : mc.parent(trans,pat)
            else: mc.parent(trans,self.localGrp)
            grp = con.emptyGroup(trans,["Zero"])
            pat = trans
            trans_list.append(trans)
            jot_con = jot_ctr+"_Con"
            mc.connectAttr(trans+".t",jot_con+".t")
            mc.connectAttr(trans+".r",jot_con+".r")
        return trans_list
    
if __name__ == '__main__':
    pass